package config

import (
	"fmt"
	"os"

	"gopkg.in/yaml.v3"
)

var AppConfig *Config

type Config struct {
	Server   ServerConfig   `yaml:"server"`
	Database DatabaseConfig `yaml:"database"`
	Redis    RedisConfig    `yaml:"redis"`
	Log      LogConfig      `yaml:"log"`
	JWT      JWTConfig      `yaml:"jwt"`
}

type ServerConfig struct {
	Port int    `yaml:"port"`
	Mode string `yaml:"mode"`
	Type string `yaml:"type"` // web, h5
}

type DatabaseConfig struct {
	Host            string `yaml:"host"`
	Port            int    `yaml:"port"`
	Username        string `yaml:"username"`
	Password        string `yaml:"password"`
	Database        string `yaml:"database"`
	Charset         string `yaml:"charset"`
	MaxIdleConns    int    `yaml:"max_idle_conns"`
	MaxOpenConns    int    `yaml:"max_open_conns"`
	ConnMaxLifetime int    `yaml:"conn_max_lifetime"`
	AutoMigrate     bool   `yaml:"auto_migrate"` // 是否启用自动迁移
}

type RedisConfig struct {
	Host      string `yaml:"host"`
	Port      int    `yaml:"port"`
	Password  string `yaml:"password"`
	Database  int    `yaml:"database"`
	PoolSize  int    `yaml:"pool_size"`
	Required  bool   `yaml:"required"`  // 是否必需，false 时连接失败不影响应用启动
	Enabled   bool   `yaml:"enabled"`   // 是否启用 Redis
}

type LogConfig struct {
	Level         string `yaml:"level"`
	File          string `yaml:"file"`
	MaxSize       int    `yaml:"max_size"`
	MaxBackups    int    `yaml:"max_backups"`
	MaxAge        int    `yaml:"max_age"`
	Compress      bool   `yaml:"compress"`
	DailyRotation bool   `yaml:"daily_rotation"`
	Required      bool   `yaml:"required"` // 是否必需，false 时初始化失败不影响应用启动
}

type JWTConfig struct {
	Secret       string `yaml:"secret"`
	ExpiresHours int    `yaml:"expires_hours"`
	Issuer       string `yaml:"issuer"`
}

func LoadConfig(path string) error {
	data, err := os.ReadFile(path)
	if err != nil {
		return fmt.Errorf("failed to read config file: %w", err)
	}

	AppConfig = &Config{}
	if err := yaml.Unmarshal(data, AppConfig); err != nil {
		return fmt.Errorf("failed to parse config file: %w", err)
	}

	return nil
}

func GetConfig() *Config {
	return AppConfig
}
